package com.martain.leetcode.t51;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 给定一个整数 n，返回所有不同的 n 皇后问题的解决方案。
 *
 * 每一种解法包含一个明确的 n 皇后问题的棋子放置方案，该方案中 'Q' 和 '.' 分别代表了皇后和空位。
 *
 *  
 *
 * 示例：
 *
 * 输入：4
 * 输出：[
 *  [".Q..",  // 解法 1
 *   "...Q",
 *   "Q...",
 *   "..Q."],
 *
 *  ["..Q.",  // 解法 2
 *   "Q...",
 *   "...Q",
 *   ".Q.."]
 * ]
 * 解释: 4 皇后问题存在两个不同的解法。
 *  
 *
 * 提示：
 *
 * 皇后彼此不能相互攻击，也就是说：任何两个皇后都不能处于同一条横行、纵行或斜线上。
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/n-queens
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class T51 {

    List<List<String>> res = new LinkedList<>();
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> board = generatorBoard(n);
        backtrack(board,0);
        return res;
    }

    public List<List<String>> generatorBoard(int n)
    {
        List<List<String>> board = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            LinkedList<String> row = new LinkedList<>();
            for (int j = 0; j < n; j++) {
                row.add(".");
            }
            board.add(row);
        }
        return board;
    }

    public String list2String(List<String> list){
        StringBuffer stringBuffer = new StringBuffer();
        for (String c :
                list) {
            stringBuffer.append(c);
        }
        return stringBuffer.toString();
    }

    public void backtrack(List<List<String>> board,int row){
        if (board.size() == row){
            List<String> _row = new ArrayList<>();
            for (int i = 0; i < board.size(); i++) {
                List<String> rowList = board.get(i);
                String rowStr = list2String(rowList);
                _row.add(rowStr);
            }
            res.add(_row);
            return;
        }
        int rowLength = board.get(row).size();
        for (int col = 0; col < rowLength; col++) {
            if (!isValid(board,row,col)){
                continue;
            }
            board.get(row).set(col,"Q");
            backtrack(board,row+1);
            board.get(row).set(col,".");
        }

    }
    
    public boolean isValid(List<List<String>> board,int row,int col)
    {
        int n = board.size();
        // 检查行上
        for (int i = 0; i < row; i++) {
            if (board.get(i).get(col).equals("Q"))
            {
                return false;
            }
        }
        // 检查左上方
        for (int i = row-1,j = col -1; i >= 0 && j>=0 ; i--,j--) {
            if (board.get(i).get(j).equals("Q")){
                return false;
            }
        }

        // 检查右上方
        for (int i = row-1,j= col+1;i>= 0 && j<n;i--,j++){
            if (board.get(i).get(j).equals("Q")){
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        T51 t51 = new T51();
        List<List<String>> result = t51.solveNQueens(4);
        System.out.println(result);
    }


}
